package com.micro.magupe.sharding.statement;

import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Collection;

public abstract class AbstractStatement extends AbstractUnsupportedOperationStatement{

    private boolean closed;
    
    private boolean poolable;
    
    private int fetchSize;
    
	@Override
	public void close() throws SQLException {
		closed = true;
		for (Statement statement : getRoutedStatements()) {
			statement.close();
		}
	}

	@Override
	public boolean isClosed() throws SQLException {
		return closed;
	}

	@Override
	public boolean isPoolable() throws SQLException {
		return poolable;
	}
	
	@Override
	public void setPoolable(boolean poolable) throws SQLException {
		this.poolable = poolable;
		
		for (Statement statement : getRoutedStatements()) {
			statement.setPoolable(poolable);
		}
	}	

	@Override
	public void setFetchSize(int rows) throws SQLException {
		this.fetchSize = rows;
		
		for (Statement statement : getRoutedStatements()) {
			statement.setFetchSize(rows);
		}
	}

	@Override
	public int getFetchSize() throws SQLException {
		return fetchSize;
	}

	@Override
	public void cancel() throws SQLException {
		for (Statement statement : getRoutedStatements()) {
			statement.cancel();
		}
	}	
	
	@Override
	public int getUpdateCount() throws SQLException {
        long result = 0;
        boolean hasResult = false;
        for (Statement each : getRoutedStatements()) {
            int updateCount = each.getUpdateCount();
            if (updateCount > -1) {
                hasResult = true;
            }
            result += updateCount;
        }
        if (result > Integer.MAX_VALUE) {
            result = Integer.MAX_VALUE;
        }
        return hasResult ? Long.valueOf(result).intValue() : -1;
	}
	
	@Override
	public void setEscapeProcessing(boolean enable) throws SQLException {
		for (Statement statement : getRoutedStatements()) {
			statement.setEscapeProcessing(enable);
		}
	}
	
	@Override
	public SQLWarning getWarnings() throws SQLException {
		return null;
	}	
	
	@Override
	public void clearWarnings() throws SQLException {
		
	}	
	
	@Override
	public int getMaxFieldSize() throws SQLException {
		return getRoutedStatements().isEmpty() ? 0 : getRoutedStatements().iterator().next().getMaxFieldSize();
	}

	@Override
	public void setMaxFieldSize(int max) throws SQLException {
		for (Statement statement : getRoutedStatements()) {
			statement.setMaxFieldSize(max);
		}
	}
	
	@Override
	public int getMaxRows() throws SQLException {
		return getRoutedStatements().isEmpty() ? -1 : getRoutedStatements().iterator().next().getMaxRows();
	}
	
	@Override
	public void setMaxRows(int max) throws SQLException {
		for (Statement statement : getRoutedStatements()) {
			statement.setMaxRows(max);
		}
	}
	
    @Override
    public final boolean getMoreResults() throws SQLException {
        boolean result = false;
        for (Statement each : getRoutedStatements()) {
            result = each.getMoreResults();
        }
        return result;
    }
    
    @Override
    public final boolean getMoreResults(final int current) {
        return false;
    }

	@Override
	public int getQueryTimeout() throws SQLException {
		return getRoutedStatements().isEmpty() ? 0 : getRoutedStatements().iterator().next().getQueryTimeout();
	}

	@Override
	public void setQueryTimeout(int seconds) throws SQLException {
		for (Statement statement : getRoutedStatements()) {
			statement.setQueryTimeout(seconds);
		}
	}

	public abstract Collection<Statement> getRoutedStatements();	
	
}
